package com.heima.aspect;


import com.heima.annotation.Title;
import com.heima.constant.BaseContextConstant;
import com.heima.context.BaseContext;
import com.heima.mapper.OperateLogMapper;
import com.heima.pojo.OperateLog;
import com.alibaba.fastjson.JSON;
import com.heima.properties.JwtProperties;
import io.swagger.annotations.Api;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.codehaus.jettison.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Arrays;

@Aspect
@Component
@Slf4j
public class OperateLogAspect {

    @Autowired
    private OperateLogMapper operateLogMapper;

    private OperateLog operateLog = new OperateLog();


    @Autowired
    HttpServletRequest request;

    @Around("execution(* com.heima.controller..*.*(..)) && @annotation(com.heima.annotation.OperationFill) ")
    public Object recodeLog(ProceedingJoinPoint joinPoint) throws Throwable {

        log.info("记录成功日志");

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();

        // 获取HTTP请求方法
        String httpMethod = request.getMethod();
        operateLog.setRequestMethod(httpMethod);

        Class<?> targetClass = joinPoint.getTarget().getClass();

        // 获取类上的注解
        Api classAnnotation = targetClass.getAnnotation(Api.class);

        //获取注解类型
        String title = classAnnotation.tags()[0];
        operateLog.setTitle(title);

        //获取HTTP请求路径
        String httpPath = request.getRequestURI();
        operateLog.setOperUrl(httpPath);

        //获取登录ip
        //todo  部署到远程后再处理
        String ip = request.getRemoteAddr();
        operateLog.setOperIp(ip);

        //操作人姓名
        String  operName = (String) BaseContext.getData(BaseContextConstant.USERNAME);
        operateLog.setOperName(operName);

        //操作时间
        LocalDateTime operTime = LocalDateTime.now();
        operateLog.setOperTime(operTime);


        //获取操作全类名
        String className = joinPoint.getTarget().getClass().getName();
        operateLog.setMethod(className);

        //获取方法执行时的参数
        Object[] args = joinPoint.getArgs();
        operateLog.setOperParam(Arrays.toString(args));

        //获取方法返回值
        Object result = joinPoint.proceed();
        operateLog.setJsonResult(JSON.toJSONString(result) );
        operateLog.setStatus(0);

        operateLogMapper.insert(operateLog);

        return result;
    }

    @AfterThrowing(pointcut = "execution(* com.heima.controller.*.*(..)) && @annotation(com.heima.annotation.OperationFill)",throwing = "ex")
    public Object throwing(Throwable ex) throws Throwable {

        log.info("记录失败日志");
        operateLog.setStatus(1);
        operateLog.setErrorMsg(ex.getMessage());
        operateLogMapper.insert(operateLog);

        return null;
    }



}
